﻿using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Wise.TimeWarrior.Interfaces;
using Wise.TimeWarrior.Impl;
using Wise.TimeWarrior.DTO;
using Wise.TimeWarrior.OSFunctionalitiesProxy;

namespace TimeWarrior.Test
{
    [TestClass]
    public class DataStorageTest
    {
        private string testDirPath;

        [TestInitialize]
        public void SetupTest()
        {

            testDirPath = Path.Combine(Path.GetTempPath(), "TimeWarriorTestTempPath");
            if (!Directory.Exists(testDirPath))
            {
                Directory.CreateDirectory(testDirPath);
            }
        }

        [TestCleanup]
        public void CleanUp()
        {
            if (Directory.Exists(testDirPath))
            {
                Directory.Delete(testDirPath, true);
            }
        }

        [TestMethod]
        public void StoreDataAndRead()
        {

            Mock<IDateTimeProvider> dateProvider = new Mock<IDateTimeProvider>();
            dateProvider.Setup(x => x.Now()).Returns(new DateTime(2013, 3, 22, 0, 0, 1));

            IDataStore dataStore = new DataStoreService();
            dataStore.DataStorePath = testDirPath;

            List<ProcessDto> processDtos = new List<ProcessDto>();

            List<UserEventDto> data = new List<UserEventDto>();
            data.Add(UserEventDto.Create(dateProvider.Object.Now(), SessionSwitchReasonExtended.SessionLogon, processDtos));
            dateProvider.Setup(x => x.Now()).Returns(new DateTime(2013, 3, 20, 0, 0, 1));
            data.Add(UserEventDto.Create(dateProvider.Object.Now(), SessionSwitchReasonExtended.SessionLogon, processDtos));
            dateProvider.Setup(x => x.Now()).Returns(new DateTime(2013, 3, 20, 7, 0, 1));
            data.Add(UserEventDto.Create(dateProvider.Object.Now(), SessionSwitchReasonExtended.SessionLogoff, processDtos));
            dateProvider.Setup(x => x.Now()).Returns(new DateTime(2013, 3, 20, 8, 0, 1));
            data.Add(UserEventDto.Create(dateProvider.Object.Now(), SessionSwitchReasonExtended.SessionLogon, processDtos));
            dateProvider.Setup(x => x.Now()).Returns(new DateTime(2013, 3, 20, 8, 10, 1));
            data.Add(UserEventDto.Create(dateProvider.Object.Now(), SessionSwitchReasonExtended.SessionLogoff, processDtos));
            dateProvider.Setup(x => x.Now()).Returns(new DateTime(2013, 3, 20, 12, 0, 1));
            data.Add(UserEventDto.Create(dateProvider.Object.Now(), SessionSwitchReasonExtended.SessionLogon, processDtos));
            dateProvider.Setup(x => x.Now()).Returns(new DateTime(2013, 3, 20, 12, 10, 1));
            data.Add(UserEventDto.Create(dateProvider.Object.Now(), SessionSwitchReasonExtended.SessionLogoff, processDtos));
            dateProvider.Setup(x => x.Now()).Returns(new DateTime(2013, 3, 20, 13, 0, 1));
            data.Add(UserEventDto.Create(dateProvider.Object.Now(), SessionSwitchReasonExtended.SessionLogon, processDtos));
            dateProvider.Setup(x => x.Now()).Returns(new DateTime(2013, 3, 20, 13, 10, 1));

            data.Add(UserEventDto.Create(dateProvider.Object.Now(), SessionSwitchReasonExtended.SessionLogon, processDtos));
            dateProvider.Setup(x => x.Now()).Returns(new DateTime(2013, 3, 21, 0, 0, 1));
            data.Add(UserEventDto.Create(dateProvider.Object.Now(), SessionSwitchReasonExtended.SessionLogon, processDtos));
            dateProvider.Setup(x => x.Now()).Returns(new DateTime(2013, 3, 21, 7, 0, 1));
            data.Add(UserEventDto.Create(dateProvider.Object.Now(), SessionSwitchReasonExtended.SessionLogoff, processDtos));
            dateProvider.Setup(x => x.Now()).Returns(new DateTime(2013, 3, 21, 8, 0, 1));
            data.Add(UserEventDto.Create(dateProvider.Object.Now(), SessionSwitchReasonExtended.SessionLogon, processDtos));
            dateProvider.Setup(x => x.Now()).Returns(new DateTime(2013, 3, 21, 8, 10, 1));
            data.Add(UserEventDto.Create(dateProvider.Object.Now(), SessionSwitchReasonExtended.SessionLogoff, processDtos));
            dateProvider.Setup(x => x.Now()).Returns(new DateTime(2013, 3, 21, 12, 0, 1));
            data.Add(UserEventDto.Create(dateProvider.Object.Now(), SessionSwitchReasonExtended.SessionLogon, processDtos));
            dateProvider.Setup(x => x.Now()).Returns(new DateTime(2013, 3, 21, 12, 10, 1));
            data.Add(UserEventDto.Create(dateProvider.Object.Now(), SessionSwitchReasonExtended.SessionLogoff, processDtos));
            dateProvider.Setup(x => x.Now()).Returns(new DateTime(2013, 3, 21, 13, 0, 1));
            data.Add(UserEventDto.Create(dateProvider.Object.Now(), SessionSwitchReasonExtended.SessionLogon, processDtos));
            dateProvider.Setup(x => x.Now()).Returns(new DateTime(2013, 3, 21, 13, 10, 1));

            data.Add(UserEventDto.Create(dateProvider.Object.Now(), SessionSwitchReasonExtended.SessionLogon, processDtos));
            dateProvider.Setup(x => x.Now()).Returns(new DateTime(2013, 3, 22, 0, 0, 1));
            data.Add(UserEventDto.Create(dateProvider.Object.Now(), SessionSwitchReasonExtended.SessionLogon, processDtos));
            dateProvider.Setup(x => x.Now()).Returns(new DateTime(2013, 3, 22, 7, 0, 1));
            data.Add(UserEventDto.Create(dateProvider.Object.Now(), SessionSwitchReasonExtended.SessionLogoff, processDtos));
            dateProvider.Setup(x => x.Now()).Returns(new DateTime(2013, 3, 22, 8, 0, 1));
            data.Add(UserEventDto.Create(dateProvider.Object.Now(), SessionSwitchReasonExtended.SessionLogon, processDtos));
            dateProvider.Setup(x => x.Now()).Returns(new DateTime(2013, 3, 22, 8, 10, 1));
            data.Add(UserEventDto.Create(dateProvider.Object.Now(), SessionSwitchReasonExtended.SessionLogoff, processDtos));
            dateProvider.Setup(x => x.Now()).Returns(new DateTime(2013, 3, 22, 12, 0, 1));
            data.Add(UserEventDto.Create(dateProvider.Object.Now(), SessionSwitchReasonExtended.SessionLogon, processDtos));
            dateProvider.Setup(x => x.Now()).Returns(new DateTime(2013, 3, 22, 12, 10, 1));
            data.Add(UserEventDto.Create(dateProvider.Object.Now(), SessionSwitchReasonExtended.SessionLogoff, processDtos));
            dateProvider.Setup(x => x.Now()).Returns(new DateTime(2013, 3, 22, 13, 0, 1));
            data.Add(UserEventDto.Create(dateProvider.Object.Now(), SessionSwitchReasonExtended.SessionLogon, processDtos));
            dateProvider.Setup(x => x.Now()).Returns(new DateTime(2013, 3, 22, 13, 10, 1));


            dataStore.SaveData(data);
            List<UserEventDto> readFromStoreDtos = dataStore.GetData(new DateTime(2012, 1, 1), null);

            Assert.AreEqual(data.Count, readFromStoreDtos.Count);

            List<UserEventDto> newListToAdd = new List<UserEventDto>();
            dateProvider.Setup(x => x.Now()).Returns(new DateTime(2013, 3, 22, 8, 0, 1));
            newListToAdd.Add(UserEventDto.Create(dateProvider.Object.Now(), SessionSwitchReasonExtended.SessionLogon, processDtos));
            dateProvider.Setup(x => x.Now()).Returns(new DateTime(2013, 3, 22, 8, 10, 1));
            newListToAdd.Add(UserEventDto.Create(dateProvider.Object.Now(), SessionSwitchReasonExtended.SessionLogoff, processDtos));
            dateProvider.Setup(x => x.Now()).Returns(new DateTime(2013, 3, 22, 12, 0, 1));
            newListToAdd.Add(UserEventDto.Create(dateProvider.Object.Now(), SessionSwitchReasonExtended.SessionLogon, processDtos));
            dateProvider.Setup(x => x.Now()).Returns(new DateTime(2013, 3, 22, 12, 10, 1));
            newListToAdd.Add(UserEventDto.Create(dateProvider.Object.Now(), SessionSwitchReasonExtended.SessionLogoff, processDtos));
            dateProvider.Setup(x => x.Now()).Returns(new DateTime(2013, 3, 22, 13, 0, 1));
            newListToAdd.Add(UserEventDto.Create(dateProvider.Object.Now(), SessionSwitchReasonExtended.SessionLogon, processDtos));


            dataStore.SaveData(newListToAdd);



            List<UserEventDto> readFromStoreDtos2 = dataStore.GetData(new DateTime(2012, 1, 1), null);

            Assert.AreEqual(readFromStoreDtos2.Count, readFromStoreDtos.Count + newListToAdd.Count);


            List<UserEventDto> readFromDate = dataStore.GetData(new DateTime(2013, 3, 21, 13, 10, 1), new DateTime(2013, 3, 21, 0, 10, 1));


            Assert.AreEqual(8, readFromDate.Count);
        }
    }
}
